﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using JUtil;
using JUtil.CodeGenerator;

namespace CodeGenerator
{
    public class BllFile : CodeGenBase, ICSharpFile
    {
        #region Constructors
        public BllFile(
            DbSetting DbSetting,
            CSharpFileSetting CSharpFileSetting,
            RelatedSql RelatedSql)
        {
            this.DbProvider = DbSetting.DbProvider;
            this.ConnectionString = DbSetting.ConnectionString;
            this.DatabaseType = DbSetting.DatabaseType;

            this.NAMESPACE = CSharpFileSetting.NAMESPACE;
            this.BLL_CLASS = CSharpFileSetting.BLL_CLASS;
            this.DAL_CLASS = CSharpFileSetting.DAL_CLASS;

            this.GetOrderBy = RelatedSql.GetOrderBy;
            this.GetSelectSQLNoOrderBy = RelatedSql.GetSelectSQLNoOrderBy;
            this.GetSelectDetailsVwSQL = RelatedSql.GetSelectDetailsVwSQL;
            this.GetInsertSQL = RelatedSql.GetInsertSQL;
            this.GetUpdateSQL = RelatedSql.GetUpdateSQL;
            this.GetDeleteSQL = RelatedSql.GetDeleteSQL;
        }
        #endregion

        #region PrivateFields
        private readonly string NAMESPACE;
        private readonly string BLL_CLASS;
        private readonly string DAL_CLASS;
        private readonly string GetOrderBy;
        private readonly string GetSelectSQLNoOrderBy;

        private readonly string GetSelectDetailsVwSQL;
        private readonly string GetInsertSQL;
        private readonly string GetUpdateSQL;
        private readonly string GetDeleteSQL;
        private readonly DbProvider DbProvider;

        private readonly string ConnectionString;
        private readonly DatabaseType DatabaseType;

        #endregion

        #region PrivateMethods
        #region SelectMethodHelper

        private delegate List<string> fnParser();

        #region TODO : Parsers

        private List<string> ParseSelectSQLNoOrderBy()
        {
            List<string> lstFields = new List<string>();

            // TODO
            // GetSelectSQLNoOrderBy
            lstFields.Add("AA");
            lstFields.Add("BB");

            return lstFields;
        }

        private List<string> ParseSelectDetailsVwSQL()
        {
            List<string> lstFields = new List<string>();

            // TODO
            // GetSelectDetailsVwSQL
            lstFields.Add("CC");
            lstFields.Add("DD");
            lstFields.Add("EE");

            return lstFields;
        }

        #endregion

        #region FunctionArguments
        private string SelectSQLNoOrderByFields
        {
            get { return GetSelectWhere(ParseSelectSQLNoOrderBy); }
        }
        private string SelectDetailsVwSQLFields
        {
            get { return GetSelectWhere(ParseSelectDetailsVwSQL); }
        }
        #endregion

        #region GetSelectWhere
        private string GetSelectWhere(fnParser parser)
        {
            StringBuilder output = new StringBuilder();

            List<string> fields = parser();
            for (int i = 0; i < fields.Count; i++)
            {
                string argument = string.Format("Convert.ToString(Parameters[\"{0}\"])", fields[i]);

                string format = (i != fields.Count - 1) ? argument + "," : argument;

                output.AppendFormat("{0}\n", format);
            }

            return output.ToString();
        }
        #endregion

        #endregion
        #region GetDalOperationContent
        private string GetDalOperationContent(string dalSql, string section)
        {
            string block = string.Empty;

            if (string.IsNullOrEmpty(dalSql))
            {
                block = "throw new NotImplementedException();";
            }
            else
            {
                block = GetTemplate(section);

                Hashtable variables = new Hashtable();

                variables["DatabaseType"] = DatabaseType;

                block = ReplaceBlock(block, variables);
            }

            return block;
        }
        #endregion

        #region GetOrderByContent
        private string GetOrderByContent
        {
            get
            {
                string block = string.Empty;

                if (string.IsNullOrEmpty(GetOrderBy))
                {
                    block = "throw new NotImplementedException();";
                }
                else
                {
                    block = GetTemplate("GetOrderByContent");
                }

                return block;
            }
        }
        #endregion
        #region GetSelectSQLNoOrderByContent
        private string GetSelectSQLNoOrderByContent
        {
            get
            {
                string block = string.Empty;

                if (string.IsNullOrEmpty(GetSelectSQLNoOrderBy))
                {
                    block = "throw new NotImplementedException();";
                }
                else
                {
                    block = GetTemplate("GetSelectSQLNoOrderByContent");

                    Hashtable variables = new Hashtable();

                    variables["SelectSQLNoOrderByFields"] = SelectSQLNoOrderByFields;

                    block = ReplaceBlock(block, variables);
                }

                return block;
            }
        }
        #endregion
        #region GetSelectDetailsVwSQLContent
        private string GetSelectDetailsVwSQLContent
        {
            get
            {
                string block = string.Empty;

                if (string.IsNullOrEmpty(GetSelectDetailsVwSQL))
                {
                    block = "throw new NotImplementedException();";
                }
                else
                {
                    block = GetTemplate("GetSelectDetailsVwSQLContent");

                    Hashtable variables = new Hashtable();

                    variables["SelectDetailsVwSQLFields"] = SelectDetailsVwSQLFields;

                    block = ReplaceBlock(block, variables);
                }

                return block;
            }
        }
        #endregion
        #region GetInsertSQLContent
        private string GetInsertSQLContent
        {
            get
            {
                return GetDalOperationContent(GetInsertSQL, "GetInsertSQLContent");
            }
        }
        #endregion
        #region GetUpdateSQLContent
        private string GetUpdateSQLContent
        {
            get
            {
                return GetDalOperationContent(GetUpdateSQL, "GetUpdateSQLContent");
            }
        }
        #endregion
        #region GetDeleteSQLContent
        private string GetDeleteSQLContent
        {
            get
            {
                return GetDalOperationContent(GetDeleteSQL, "GetDeleteSQLContent");
            }
        }
        #endregion
        #endregion

        #region OverrideMethods

        protected override void AssignExportTemplate(System.Collections.Hashtable Variables)
        {
            Variables["USING_NAMESPACES"] = USING_NAMESPACES;
            Variables["NAMESPACE"] = GetNameSpace();
            Variables["BLL_CLASS"] = BLL_CLASS;
            Variables["DAL_CLASS"] = DAL_CLASS;
            Variables["DbProvider"] = DbProvider.ToString();
            Variables["ConnectionString"] = ConnectionString;

            Variables["GetOrderByContent"] = GetOrderByContent;
            Variables["GetSelectSQLNoOrderByContent"] = GetSelectSQLNoOrderByContent;
            Variables["GetSelectDetailsVwSQLContent"] = GetSelectDetailsVwSQLContent;
            Variables["GetInsertSQLContent"] = GetInsertSQLContent;
            Variables["GetUpdateSQLContent"] = GetUpdateSQLContent;
            Variables["GetDeleteSQLContent"] = GetDeleteSQLContent;
        }
        
        protected override string GetExportTemplate()
        {
            return GetTemplate("ExportTemplate");
        }

        #endregion

        #region ICSharpFile 成員

        public string USING_NAMESPACES
        {
            get
            {
                List<string> lstUsingNameSpace = new List<string>
                {
                    "System",
                    "System.Collections",
                    "System.Collections.Generic",
                    "System.ComponentModel",
                    "JUtil",
                    "JUtil.ResourceManagement",
                    "JUtil.Web"
                };

                StringBuilder output = new StringBuilder();

                foreach (string ns in lstUsingNameSpace)
                {
                    output.AppendFormat("using {0};\n", ns);
                }

                return output.ToString();
            }
        }

        public string GetNameSpace()
        {
            return NAMESPACE;
        }

        public string GetClass()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
